from django.core.paginator import Paginator
from django.shortcuts import render
from django import http
from django.views import View

from apps.contents.utils import get_categories
from apps.goods.models import GoodsCategory, SKU, GoodsVisitCount
from apps.goods.utils import get_breadcrumb
from utils.response_code import RETCODE


class ListView(View):
    """
    1.分类数据
    2.面包屑
    3. 列表数据
    """
    def get(self,request,category_id,page_num):
        # 分类数据
        categories = get_categories()
        # 获取面包屑数据
        # 面包屑数据其实就是分类数据
        # 当用户点击某一个分类时，就应该将这个分类id传递给我们
        try:
            # 获取的是三级分类
            category = GoodsCategory.objects.get(pk=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseBadRequest("分类错误")
        # 因为面包屑在多个地方使用到了，所以直接抽取
        breadcrumb = get_breadcrumb(category)

        # 列表数据的获取
        # 1.获取所有数据
        # 2.排序数据

        # 先获取到查询字符串的数据
        # get(key,dafault_value)
        # 当获取值的时候，这个key所对应的值为None的时候，则获取默认值
        sort = request.GET.get('sort','dafault')
        if sort == 'default':
            sort_file = 'create_time'
        elif sort == 'price':
            sort_file = 'price'
        else:
            sort = 'hot'
            sort_file = '-sales'
        skus = SKU.objects.filter(category=category).order_by(sort_file)

        # 分页数据
        # object_list 所有的数据
        # per_page 每页多少条数据
        paginator = Paginator(skus,5)

        # 获取当前页码所对应的数据
        try:
            page_num = int(page_num)
            page_skus = paginator.page(page_num)
        except Exception as e:
            pass
        total_page = paginator.num_pages
        context = {
            "categories": categories,
            "breadcrumb": breadcrumb,
            "page_num": page_num,
            "category":category,
            "sort":sort,
            "total_page":total_page,
            "page_skus":page_skus

        }
        return render(request,'list.html',context=context)

"""
响应状态码：
    200 成功
    300 重定向
    404 找不到页面(路由问题)
    403 禁止访问(权限问题/没有登录)
    500 服务器问题(后端代码)
"""

# 热销数据的获取
class HotView(View):
    """
    需求：
        1.根据分类查询数据，查询之后排序，排序之后获取两条数据
        2.热销数据在一段时间内不会发生变化，可以做缓存
    """
    def get(self,request,category_id):
        skus = SKU.objects.filter(category_id=category_id).order_by('-sales')[0:2]
        # skus = SKU.objects.filter(category_id=category_id).order_by('-sales')[:2]
        # 将对象列表转换为字典列表
        hot_skus = []
        for sku in skus:
            hot_skus.append({
                "id": sku.id,
                "price": sku.price,
                "default_image_url": sku.default_image.url,
                "name": sku.name
            })
        return http.JsonResponse({"code": RETCODE.OK,"errmsg": "ok","hot_skus": hot_skus})


# 商品详情的展示
class DetailView(View):
    def get(self,request,sku_id):
        # 获取当前sku信息
        try:
            sku = SKU.objects.get(pk=sku_id)
        except SKU.DoesNotExist:
            return render(request,'404.html')

        # 查询商品频道分类
        categories = get_categories()
        # 查询面包屑导航
        breadcrumb = get_breadcrumb(sku.category)

        # 构建当前商品的规格键
        sku_specs = sku.specs.order_by('spec_id')
        sku_key = []
        for spec in sku_specs:
            sku_key.append(spec.option.id)
        # 获取当前商品的所有SKU
        skus = sku.spu.sku_set.all()
        # 构建不同规格参数（选项）的sku字典
        spec_sku_map = {}
        for s in skus:
            # 获取sku的规格参数
            s_specs = s.specs.order_by('spec_id')
            # 用于形成规格参数-sku字典的键
            key = []
            for spec in s_specs:
                key.append(spec.option.id)
            # 向规格参数-sku字典添加记录
            spec_sku_map[tuple(key)] = s.id
        # 获取当前商品的规格信息
        goods_specs = sku.spu.specs.order_by('id')
        # 若当前sku的规格信息不完整，则不再继续
        if len(sku_key) < len(goods_specs):
            return
        for index, spec in enumerate(goods_specs):
            # 复制当前sku的规格键
            key = sku_key[:]
            # 该规格的选项
            spec_options = spec.options.all()
            for option in spec_options:
                # 在规格参数sku字典中查找符合当前规格的sku
                key[index] = option.id
                option.sku_id = spec_sku_map.get(tuple(key))
            spec.spec_options = spec_options

        # 渲染页面
        context = {
            "caregories": categories,
            "breadcrumb": breadcrumb,
            "sku": sku,
            'specs': goods_specs,
        }

        return render(request,'detail.html',context=context)


# 商品的分类统计
class CategoryVisitView(View):
    """
    需求：
        1.当用户点击详情页面（列表页面）的时候，我们需要让前端将分类id传递给后端
        2.后端对分类数据进行+1的统计
    后端：
        1.接受数据
        2.查询对应的分类信息
        3.统计数据的更新
        4.返回数据
    """
    def post(self,request,category_id):
        # 查询分类信息
        try:
            category = GoodsCategory.objects.get(pk=category_id)
        except GoodsCategory.DoesNotExist:
            return http.JsonResponse({"code":RETCODE.NODATAERR,"errmsg":"没有此分类！"})

        #　今天的日期
        from django.utils import timezone
        today = timezone.localdate()
        # 统计数据的更新
        try:
            gvc = GoodsVisitCount.objects.get(category=category,date=today)
        except GoodsVisitCount.DoesNotExist:
            # 查询不到　创建新的统计数据
            gvc = GoodsVisitCount(
                category=category,
                count=1,
                date=today
            )
            gvc.save()
        else:
            gvc.count+=1
            gvc.save()

        return http.JsonResponse({"code":RETCODE.OK,"errmsg":"ok"})


